package com.quanqiutong.hprt_cpcl;

import androidx.annotation.NonNull;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;

import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.Toast;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;

import java.io.InputStream;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;

import cpcl.PrinterHelper;
import com.quanqiutong.hprt_cpcl.utils.BitmapUtil;

/** HprtCpclPlugin */
public class HprtCpclPlugin implements FlutterPlugin, MethodCallHandler {
  /// The MethodChannel that will the communication between Flutter and native
  /// Android
  ///
  /// This local reference serves to register the plugin with the Flutter Engine
  /// and unregister it
  /// when the Flutter Engine is detached from the Activity
  private MethodChannel channel;
  private Context context;

  @Override
  public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
    System.out.println("onAttachedToEngine");
    this.context = flutterPluginBinding.getApplicationContext();
    channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "hprt_cpcl");
    channel.setMethodCallHandler(this);
  }

  private Map<String, String> getBLEDevices() {
    Map<String, String> map = new HashMap<String, String>();
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if (bluetoothAdapter == null) {
      // 设备不支持蓝牙
      return map;
    }
    if (!bluetoothAdapter.isEnabled()) {
      // 蓝牙未开启
      return map;
    }
    Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices();
    for (BluetoothDevice device : bondedDevices) {
      if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
        String deviceName = device.getName();
        String deviceAddress = device.getAddress();
        map.put(deviceAddress, deviceName);
      }
    }
    return map;
  }

  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
    try {
      int res = 1;
      Map arg = call.arguments();
      System.out.println(call.method);
      System.out.println(arg);
      if (call.method.equals("portOpenBT")) {
        res = PrinterHelper.portOpenBT(context, (String) arg.get("portSetting"));
      } else if (call.method.equals("portClose")) {
        PrinterHelper.portClose();
        res = 1;
      } else if (call.method.equals("devices")) {
        Map<String, String> map = getBLEDevices();
        result.success(map);
        return;
      } else if (call.method.equals("printAreaSize")) {
        res = PrinterHelper.printAreaSize((String) arg.get("offset"), (String) arg.get("horizontal"),
            (String) arg.get("vertical"), (String) arg.get("height"), (String) arg.get("qty"));
      } else if (call.method.equals("print")) {
        res = PrinterHelper.Print();
      } else if (call.method.equals("encoding")) {
        res = PrinterHelper.Encoding((String) arg.get("code"));
      } else if (call.method.equals("form")) {
        res = PrinterHelper.Form();
      } else if (call.method.equals("note")) {
        res = PrinterHelper.Note((String) arg.get("note"));
      } else if (call.method.equals("abort")) {
        res = PrinterHelper.Abort();
      } else if (call.method.equals("text")) {
        String command = null;
        if (arg.get("command").equals("TEXT")) {
          command = PrinterHelper.TEXT;
        } else if (arg.get("command").equals("TEXT90")) {
          command = PrinterHelper.TEXT90;
        } else if (arg.get("command").equals("TEXT180")) {
          command = PrinterHelper.TEXT180;
        } else if (arg.get("command").equals("TEXT270")) {
          command = PrinterHelper.TEXT270;
        }
        res = PrinterHelper.Text(command, (String) arg.get("font"), "0",
            (String) arg.get("x"), (String) arg.get("y"), (String) arg.get("data"));
      } else if (call.method.equals("printTextCPCL")) {
        String command = null;
        if (arg.get("command").equals("TEXT")) {
          command = PrinterHelper.TEXT;
        } else if (arg.get("command").equals("TEXT270")) {
          command = PrinterHelper.TEXT270;
        }
        res = PrinterHelper.PrintTextCPCL(command, (int) arg.get("font"),
            (String) arg.get("x"), (String) arg.get("y"), (String) arg.get("data"), (int) arg.get("n"),
            (boolean) arg.get("isCenter"), (int) arg.get("width"));
      } else if (call.method.equals("printCodepageTextCPCL")) {
        String command = null;
        if (arg.get("command").equals("TEXT")) {
          command = PrinterHelper.TEXT;
        } else if (arg.get("command").equals("TEXT270")) {
          command = PrinterHelper.TEXT270;
        }
        res = PrinterHelper.PrintCodepageTextCPCL(command, (int) arg.get("font"),
            (String) arg.get("x"), (String) arg.get("y"), (String) arg.get("data"), (int) arg.get("n"));
      } else if (call.method.equals("count")) {
        res = PrinterHelper.Count((String) arg.get("ml"));
      } else if (call.method.equals("setMag")) {
        res = PrinterHelper.SetMag((String) arg.get("width"), (String) arg.get("height"));
      } else if (call.method.equals("align")) {
        String align = null;
        if (arg.get("align").equals("center")) {
          align = PrinterHelper.CENTER;
        } else if (arg.get("align").equals("left")) {
          align = PrinterHelper.LEFT;
        } else if (arg.get("align").equals("right")) {
          align = PrinterHelper.RIGHT;
        }
        res = PrinterHelper.Align(align);
      } else if (call.method.equals("barcode")) {
        String command;
        if (arg.get("command").equals("BARCODE")) {
          command = PrinterHelper.BARCODE;
        } else {
          command = PrinterHelper.VBARCODE;
        }
        res = PrinterHelper.Barcode(command, PrinterHelper.code128, (String) arg.get("width"),
            (String) arg.get("ratio"),
            (String) arg.get("height"), (String) arg.get("x"), (String) arg.get("y"), (boolean) arg.get("undertext"),
            (String) arg.get("number"), (String) arg.get("size"), (String) arg.get("offset"), (String) arg.get("data"));
      } else if (call.method.equals("printQR")) {
        String command;
        if (arg.get("command").equals("BARCODE")) {
          command = PrinterHelper.BARCODE;
        } else {
          command = PrinterHelper.VBARCODE;
        }
        res = PrinterHelper.PrintQR(command, (String) arg.get("x"), (String) arg.get("y"),
            (String) arg.get("m"), (String) arg.get("u"), (String) arg.get("data"));
      }

      else if (call.method.equals("printQRCodeImage")) {

        Bitmap bitmap = BitmapUtil.generateBitmap((String) arg.get("data"), 9,
            (int) arg.get("width"), (int) arg.get("height"));

        res = PrinterHelper.printBitmapCPCL(bitmap, (int) arg.get("x"), (int) arg.get("y"), (int) arg.get("type"),
            (int) arg.get("compressType"), (int) arg.get("light"));

      }

      else if (call.method.equals("box")) {
        res = PrinterHelper.Box((String) arg.get("x0"), (String) arg.get("y0"),
            (String) arg.get("x1"), (String) arg.get("y1"), (String) arg.get("width"));
      } else if (call.method.equals("line")) {
        res = PrinterHelper.Line((String) arg.get("x0"), (String) arg.get("y0"),
            (String) arg.get("x1"), (String) arg.get("y1"), (String) arg.get("width"));
      } else if (call.method.equals("inverseLine")) {
        res = PrinterHelper.InverseLine((String) arg.get("x0"), (String) arg.get("y0"),
            (String) arg.get("x1"), (String) arg.get("y1"), (String) arg.get("width"));
      } else if (call.method.equals("printBitmapCPCL")) {
        byte[] b = (byte[]) arg.get("bytes");
        Bitmap bmp = null;
        if (b.length != 0) {
          bmp = BitmapFactory.decodeByteArray(b, 0, b.length);
        }
        res = PrinterHelper.printBitmapCPCL(bmp, (int) arg.get("x"), (int) arg.get("y"), (int) arg.get("type"),
            (int) arg.get("compressType"), (int) arg.get("light"));
      } else if (call.method.equals("printBitmap")) {
        byte[] b = (byte[]) arg.get("bytes");
        Bitmap bmp = null;
        if (b.length != 0) {
          bmp = BitmapFactory.decodeByteArray(b, 0, b.length);
        }

        int height = (int) arg.get("height");
        int width = (int) arg.get("width");
        int rotate = (int) arg.get("rotate");
        if (height > 0 && width > 0) {
          bmp = BitmapUtil.Tobitmap(bmp, width, height);
        }
        if (rotate > 0) {
          bmp = BitmapUtil.Rotate(bmp, rotate);
        }

        res = PrinterHelper.printBitmap((int) arg.get("x"), (int) arg.get("y"), (int) arg.get("type"), bmp,
            (int) arg.get("compressType"), (boolean) arg.get("isform"), (int) arg.get("segments"));
      } else if (call.method.equals("contrast")) {
        res = PrinterHelper.Contrast((String) arg.get("contrast"));
      } else if (call.method.equals("speed")) {
        res = PrinterHelper.Speed((String) arg.get("speed"));
      } else if (call.method.equals("setSp")) {
        res = PrinterHelper.SetSp((String) arg.get("setsp"));
      } else if (call.method.equals("preFeed")) {
        res = PrinterHelper.Prefeed((String) arg.get("prefeed"));
      } else if (call.method.equals("postFeed")) {
        res = PrinterHelper.Postfeed((String) arg.get("posfeed"));
      } else if (call.method.equals("beep")) {
        res = PrinterHelper.Beep((String) arg.get("beep"));
      } else if (call.method.equals("underline")) {
        res = PrinterHelper.Underline((boolean) arg.get("ul"));
      } else if (call.method.equals("wait")) {
        res = PrinterHelper.Wait((String) arg.get("wait"));
      } else if (call.method.equals("setlf")) {
        res = PrinterHelper.Setlf((String) arg.get("sf"));
      } else if (call.method.equals("pageWidth")) {
        res = PrinterHelper.PageWidth((String) arg.get("pw"));
      } else if (call.method.equals("setlp")) {
        res = PrinterHelper.Setlp((String) arg.get("font"), (String) arg.get("size"), (String) arg.get("spacing"));
      } else if (call.method.equals("writeData")) {
        res = PrinterHelper.WriteData((byte[]) arg.get("bData"));
      } else if (call.method.equals("setBold")) {
        res = PrinterHelper.SetBold((String) arg.get("bold"));
      } else if (call.method.equals("getStatus")) {
        res = PrinterHelper.getstatus();
      } else if (call.method.equals("autLine")) {
        res = PrinterHelper.AutLine((String) arg.get("x"), (String) arg.get("y"), (int) arg.get("width"),
            (int) arg.get("size"), (boolean) arg.get("isbole"), (boolean) arg.get("isdouble"), (String) arg.get("str"));
      } else if (call.method.equals("autLine2")) {
        res = PrinterHelper.AutLine2((String) arg.get("x"), (String) arg.get("y"), (String) arg.get("width"),
            (int) arg.get("size"), (boolean) arg.get("isbole"), (boolean) arg.get("isdouble"), (String) arg.get("str"));
      } else if (call.method.equals("autCenter")) {
        String command;
        if (arg.get("command").equals("TEXT")) {
          command = PrinterHelper.TEXT;
        } else {
          command = PrinterHelper.TEXT270;
        }
        res = PrinterHelper.AutCenter(command, (String) arg.get("x"), (String) arg.get("y"), (int) arg.get("width"),
            (int) arg.get("size"), (String) arg.get("str"));
      } else if (call.method.equals("paperTypeCPCL")) {
        PrinterHelper.papertype_CPCL((int) arg.get("page"));
        res = 1;
      } else if (call.method.equals("setSelf")) {
        PrinterHelper.setSelf();
        res = 1;
      } else if (call.method.equals("poPrint")) {
        res = PrinterHelper.PoPrint();
      } else if (call.method.equals("openEndStatic")) {
        PrinterHelper.openEndStatic((boolean) arg.get("isopen"));
        res = 1;
      } else if (call.method.equals("getEndStatus")) {
        res = PrinterHelper.getEndStatus((int) arg.get("time"));
      } else if (call.method.equals("reverseFeed")) {
        res = PrinterHelper.ReverseFeed((int) arg.get("feed"));
      } else if (call.method.equals("printBackground")) {
        res = PrinterHelper.PrintBackground((int) arg.get("x"), (int) arg.get("y"), (int) arg.get("size"),
            (int) arg.get("background"), (String) arg.get("data"));
      } else if (call.method.equals("country")) {
        res = PrinterHelper.Country((String) arg.get("codepage"));
      } else if (call.method.equals("setQRcodeVersion")) {
        res = PrinterHelper.setQRcodeVersion((int) arg.get("version"));
      } else if (call.method.equals("printData")) {
        res = PrinterHelper.PrintData((String) arg.get("str"));
      } else if (call.method.equals("rowSetBold")) {
        res = PrinterHelper.RowSetBold((String) arg.get("bold"));
      } else if (call.method.equals("rowSetX")) {
        res = PrinterHelper.RowSetX((String) arg.get("x"));
      } else {
        result.notImplemented();
      }
      result.success(res);
    } catch (Exception e) {
      result.error("0", e.getMessage(), "");
    }
  }

  @Override
  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
    channel.setMethodCallHandler(null);
  }
}
